﻿namespace SFWS.XHandler.Core
{
    using SFWS.XHandler.Core.Properties;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Reflection;
    using System.Web;

    internal sealed class Mapping
    {
        private Dictionary<string, MappingNode> pathmapping = null;
        private static Mapping pm = new Mapping();
        private Dictionary<string, Type> typemapping = new Dictionary<string, Type>();

        private Mapping()
        {
        }

        private object[] CurrentMappedType(bool isroot, string rootpath, string path, MappingNode node)
        {
            int length = path.LastIndexOf(AppUtility.GetConfValue(Resources.ConfSectionName, Resources.ConfKey_PathSuffix));
            path = path.Substring(0, length).Replace("/", ".");
            string cc = node.Assembly.GetName().Name;
            string key = node.Assembly.GetName().Name + "." + path + node.HandlerSuffix;
            if (this.typemapping.ContainsKey(key))
            {
                return new object[] { node, this.typemapping[key] };
            }
            Type type = null;
            try
            {
                type = node.Assembly.GetType(key, false, true);
                this.typemapping.Add(key, type);
            }
            catch
            {
            }
            if ((type == null) && !isroot)
            {
                MappingNode node2 = this[""];
                if (node2 != null)
                {
                    return this.CurrentMappedType(true, rootpath, rootpath, node2);
                }
            }
            return new object[] { node, type };
        }

        private void ParseMapping()
        {
            this.pathmapping = new Dictionary<string, MappingNode>();
            string[] strArray = AppUtility.GetConfValue(Resources.ConfSectionName, Resources.ConfKey_PathMapping).Split(new char[] { '|' });
            for (int i = 0; i < strArray.Length; i++)
            {
                string[] strArray2 = strArray[i].Split(new char[] { ',' });
                if (strArray2.Length >= 2)
                {
                    string key = strArray2[0].Trim().ToLower();
                    string assemblyName = strArray2[1].Trim();
                    string defaultTypeSuffix = Resources.DefaultTypeSuffix;
                    string str4 = "1";
                    if (strArray2.Length > 2)
                    {
                        defaultTypeSuffix = strArray2[2].Trim();
                    }
                    if (strArray2.Length > 3)
                    {
                        str4 = strArray2[3].Trim();
                    }
                    if (((assemblyName != "") && !this.pathmapping.ContainsKey(key)) && (key.IndexOfAny(Path.GetInvalidFileNameChars()) <= -1))
                    {
                        MappingNode node = new MappingNode(key, assemblyName, defaultTypeSuffix, str4.Equals("0"));
                        this.pathmapping.Add(key, node);
                    }
                }
            }
        }

        public static Mapping Current
        {
            get
            {
                return pm;
            }
        }

        internal object[] CurrentMapping
        {
            get
            {
                string str3;
                string path = HttpContext.Current.Request.Path;
                string applicationPath = HttpContext.Current.Request.ApplicationPath;
                if (applicationPath == "/")
                {
                    applicationPath = "";
                }
                path = path.Substring(applicationPath.Length + 1);
                string rootpath = path;
                int index = path.IndexOf("/");
                if (index < 0)
                {
                    str3 = "";
                }
                else
                {
                    str3 = path.Substring(0, index);
                    path = path.Substring(index + 1);
                }
                MappingNode node = this[str3];
                if (node == null)
                {
                    if (str3 != "")
                    {
                        node = this[""];
                    }
                    if (node == null)
                    {
                        return null;
                    }
                    str3 = "";
                    path = rootpath;
                }
                return this.CurrentMappedType(str3 == "", rootpath, path, node);
            }
        }

        public MappingNode this[string path]
        {
            get
            {
                if (path == null)
                {
                    return null;
                }
                if (this.pathmapping == null)
                {
                    this.ParseMapping();
                }
                Dictionary<string, MappingNode> dictionary = this.pathmapping ?? new Dictionary<string, MappingNode>();
                string key = path.ToLower();
                return (dictionary.ContainsKey(key) ? dictionary[key] : null);
            }
        }
    }
}

